Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
I can push this to 1.10 if we don't want to rush here.
| -- Parse recipients from inline code output or plain text | ||
| -- Supports multiple formats: | ||
| -- 1. Python list: ['a', 'b'] or ["a", "b"] | ||
| -- 2. R vector: "a" "b" "c" | ||
| -- 3. Comma-separated: a, b, c | ||
| -- 4. Line-separated: a\nb\nc | ||
| -- Returns an empty array if parsing fails | ||
| function parse_recipients(recipient_str) |
There was a problem hiding this comment.
The approach here is parsing through various printed versions of list/vectors in Python + R and then extract the strings inside of them which (presumably) works (I haven't checked the tests yet, so maybe there actually are corner cases or bugs or something, but either way...).
What if, instead, we do the opposite: look for email addresses in the string and ignore everything else. My lua is not strong ™️ but Claude came up with the following:
recipients = {}
for email in string.gmatch(recipient_str, "[%w%._%+%-]+@[%w%.%-]+%.%w+") do
table.insert(recipients, email)
end
if #recipients > 0 then
return recipients
end
No need to detect [...] vs list(...) vs c(...), no comma splitting, no quote
stripping (ASCII or curly), no bracket removal, no trimming. The email pattern
cuts through all of that because the surrounding syntax (quotes, brackets,
commas, spaces) will never match the email pattern — it naturally rejects all
of it.
What do you think of doing it that way?
Description
This PR adds support for dynamic email recipients in the
emailformat for Posit Connect. Recipients can now be computed programmatically via Python or R code and specified in multiple formats.Key Features
write_yaml_metadata_block()in R or equivalent in Python)v2 Metadata Structure
We now return v2 which looks identical to the changes in #13882, but with a recipients field:
{ "emails": [ { "attachments": [], "body_html": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\"> <!-- utf-8 works for most cases -->\n<meta name=\"viewport\" content=\"width=device-width\"> <!-- Forcing initial-scale shouldn't be necessary -->\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"> <!-- Use the latest (edge) version of IE rendering engine -->\n<meta name=\"x-apple-disable-message-reformatting\"> <!-- Disable auto-scale in iOS 10 Mail entirely -->\n<meta name=\"format-detection\" content=\"telephone=no,address=no,email=no,date=no,url=no\"> <!-- Tell iOS not to automatically link certain text strings. -->\n<meta name=\"color-scheme\" content=\"light\">\n<meta name=\"supported-color-schemes\" content=\"light\">\n<!-- What it does: Makes background images in 72ppi Outlook render at correct size. -->\n<!--[if gte mso 9]>\n<xml>\n<o:OfficeDocumentSettings>\n<o:AllowPNG/>\n<o:PixelsPerInch>96</o:PixelsPerInch>\n</o:OfficeDocumentSettings>\n</xml>\n<![endif]-->\n<style>\nbody {\nfont-family: Helvetica, sans-serif;\nfont-size: 14px;\n}\n.content {\nbackground-color: white;\n}\n.content .message-block {\nmargin-bottom: 24px;\n}\n.header .message-block, .footer message-block {\nmargin-bottom: 12px;\n}\nimg {\nmax-width: 100%;\n}\n@media only screen and (max-width: 767px) {\n.container {\nwidth: 100%;\n}\n.articles, .articles tr, .articles td {\ndisplay: block;\nwidth: 100%;\n}\n.article {\nmargin-bottom: 24px;\n}\n}\n</style>\n</head>\n<body style=\"background-color:#f6f6f6;font-family:Helvetica, sans-serif;color:#222;margin:0;padding:0;\">\n<table width=\"85%\" align=\"center\" class=\"container\" style=\"max-width:1000px;\">\n<tr>\n<td style=\"padding:24px;\">\n<div class=\"header\" style=\"font-family:Helvetica, sans-serif;color:#999999;font-size:12px;font-weight:normal;margin:0 0 24px 0;text-align:center;\">\n</div>\n<table width=\"100%\" class=\"content\" style=\"background-color:white;\">\n<tr>\n<td style=\"padding:12px;\">\n<p>First email HTML content.</p>\n</td></tr>\n</table>\n<div class=\"footer\" style=\"font-family:Helvetica, sans-serif;color:#999999;font-size:12px;font-weight:normal;margin:24px 0 0 0;\">\n<p>This message was generated on 2026-01-16 16:15:12.</p>\n\n<p>If HTML documents are attached, they may not render correctly when viewed in some email clients. For a better experience, download HTML documents to disk before opening in a web browser.</p>\n</div>\n</td>\n</tr>\n</table>\n</body>\n</html>\n", "body_text": "Text version of first email.\n", "email_id": 1, "recipients": [ "a@example.com", "b@example.com", ], "send_report_as_attachment": false, "subject": "First Email Subject", "suppress_scheduled": false }, { "attachments": [], "body_html": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\"> <!-- utf-8 works for most cases -->\n<meta name=\"viewport\" content=\"width=device-width\"> <!-- Forcing initial-scale shouldn't be necessary -->\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"> <!-- Use the latest (edge) version of IE rendering engine -->\n<meta name=\"x-apple-disable-message-reformatting\"> <!-- Disable auto-scale in iOS 10 Mail entirely -->\n<meta name=\"format-detection\" content=\"telephone=no,address=no,email=no,date=no,url=no\"> <!-- Tell iOS not to automatically link certain text strings. -->\n<meta name=\"color-scheme\" content=\"light\">\n<meta name=\"supported-color-schemes\" content=\"light\">\n<!-- What it does: Makes background images in 72ppi Outlook render at correct size. -->\n<!--[if gte mso 9]>\n<xml>\n<o:OfficeDocumentSettings>\n<o:AllowPNG/>\n<o:PixelsPerInch>96</o:PixelsPerInch>\n</o:OfficeDocumentSettings>\n</xml>\n<![endif]-->\n<style>\nbody {\nfont-family: Helvetica, sans-serif;\nfont-size: 14px;\n}\n.content {\nbackground-color: white;\n}\n.content .message-block {\nmargin-bottom: 24px;\n}\n.header .message-block, .footer message-block {\nmargin-bottom: 12px;\n}\nimg {\nmax-width: 100%;\n}\n@media only screen and (max-width: 767px) {\n.container {\nwidth: 100%;\n}\n.articles, .articles tr, .articles td {\ndisplay: block;\nwidth: 100%;\n}\n.article {\nmargin-bottom: 24px;\n}\n}\n</style>\n</head>\n<body style=\"background-color:#f6f6f6;font-family:Helvetica, sans-serif;color:#222;margin:0;padding:0;\">\n<table width=\"85%\" align=\"center\" class=\"container\" style=\"max-width:1000px;\">\n<tr>\n<td style=\"padding:24px;\">\n<div class=\"header\" style=\"font-family:Helvetica, sans-serif;color:#999999;font-size:12px;font-weight:normal;margin:0 0 24px 0;text-align:center;\">\n</div>\n<table width=\"100%\" class=\"content\" style=\"background-color:white;\">\n<tr>\n<td style=\"padding:12px;\">\n<p>Second email HTML content.</p>\n</td></tr>\n</table>\n<div class=\"footer\" style=\"font-family:Helvetica, sans-serif;color:#999999;font-size:12px;font-weight:normal;margin:24px 0 0 0;\">\n<p>This message was generated on 2026-01-16 16:15:12.</p>\n\n<p>If HTML documents are attached, they may not render correctly when viewed in some email clients. For a better experience, download HTML documents to disk before opening in a web browser.</p>\n</div>\n</td>\n</tr>\n</table>\n</body>\n</html>\n", "body_text": "Text version of second email.\n", "email_id": 2, "recipients": [ "c@example.com", "d@example.com", ], "send_report_as_attachment": false, "subject": "Second Email Subject", "suppress_scheduled": false } ], "rsc_email_version": 2 }Dynamic recipients (inline Python/R):
Dynamic recipients (metadata Python):
Dynamic recipients (metadata R):
Closes #14023
Checklist
I have (if applicable):